home *** CD-ROM | disk | FTP | other *** search
-
- ; /*\
- ;---|*|----====< MIXERC.C >====----
- ;---|*|
- ;---|*| Initialize and setup the access to the mixers, volume, filter, etc
- ;---|*|
- ;---|*| Copyright (c) 1991, Media Vision, Inc. All rights reserved
- ;---|*|
- ; \*/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include "mixbin.h" // the actual mixer code
- #include "state.h" // the state structure
-
- ; /*\
- ;---|*|---------------====< Programming Caveat >====--------------\
- ;---|*| |
- ;---|*| This code is provided for documentation ONLY. It has been |
- ;---|*| replaced by MIXERC.C. Please use the newer body of code |
- ;---|*| for all your development, thus avoiding hardware depend- |
- ;---|*| encies. |
- ;---|*| |
- ;---|*|---------------====< Programming Caveat >====--------------/
- ; \*/
-
- int ThePASDMAChannel = 0; // DMA channel
- int ThePASIRQChannel = 0; // IRQ channel
-
- static int dummyroutine ();
-
- int (far *MVSetMixerFunction) () = 0;
- int (far *MVSetVolumeFunction) () = 0;
- int (far *MVSetFilterFunction) () = 0;
- int (far *MVSetCrossChannel) () = 0;
- int (far *MVGetMixerFunction) () = 0;
- int (far *MVGetVolumeFunction) () = 0;
- int (far *MVGetFilterFunction) () = 0;
- int (far *MVGetCrossChannel) () = 0;
- int (far *MVRealSoundSwitch) () = 0;
- int (far *MVFMSplitSwitch) () = 0;
-
- #define STATICDRIVER 0x0000 // The static driver is loaded.
- #define DOSDRIVER 0x0001 // The DOS driver is loaded.
- #define DISKDRIVER 0x0002 // The Disk resident driver is loaded.
-
- extern struct MVState far *mvhwShadowPointer;
- static struct MVState far *(far *MVMixerHWStateFunction)() = 0;
- struct MVState far *MVMixerHWState(struct MVState far *);
-
- ////
- ////; /*\
- ////;---|*|----====< test code >====----
- ////;---|*|
- ////;---|*| this is test code to be removed
- ////;---|*|
- ////; \*/
- //// int main()
- //// {
- ////
- //// // In each of the following calls, MVInitMixerCode will search for
- //// // the DOS driver, "MVSOUND.SYS". If found, all succeeding calls to
- //// // the mixers will be routed through MVSOUND.SYS. If the DOS driver
- //// // is not found, then either the DISK based version, or the static
- //// // version will be used. To select the DISK based version, pass a
- //// // path to MVInitMixerCode. Any pointer (other than a NULL) will tell
- //// // the routine to load the driver from the disk. NOTE: If loading from
- //// // the disk fails, then the static driver will be used.
- ////
- //// //
- //// // EXAMPLE #1 - The following will attempt to
- //// // load the driver from the disk.
- ////
- //// MVInitMixerCode ( "." );
- ////
- //// //
- //// // EXAMPLE #2 - the following will use the
- //// // static built-in driver.
- ////
- //// MVInitMixerCode ( 0 );
- //// }
- ////
-
- ; /*\
- ;---|*|----====< MVInitMixerCode >====----
- ;---|*|
- ;---|*| Load link to the DOS driver, or load the mixer code
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| char *path is the path to the disk resident driver.
- ;---|*|
- ;---|*| Return Value:
- ;---|*| 0, the mixer code is using the static driver.
- ;---|*| 1, the mixer code is using DOS driver.
- ;---|*| 2, the mixer code is using Disk resident driver.
- ;---|*|
- ; \*/
- int MVInitMixerCode(path)
- char *path;
- {
- char *p,*p1;
- int n,mx,tablelen;
- long far *bfp; // buffer far pointer
- long far *tfp; // table far pointer
- long mvver; // MVSOUND.SYS version #
-
- static int retry = 0; // reentry flag. We will only execute once
- static int retcode = 0;
-
- // exit if this code has already been executed
-
- if (retry++)
- return(retcode);
-
- // flush some variables
-
- mx = 0;
-
- _asm {
-
- ; fixup the linked in code to be on a paragraph alignment
-
- push es
- push di
- push si
-
- mov bx,ds
- mov es,bx
-
- mov di,offset code_block ; get the start of the block
- mov si,17 ; # of leading zeros in code_block
- add si,di ; si points to the start
- and di,0xfff0 ; knock out the low nibble
- add di,0x10 ; move back up to a starting place
-
- sbb ax,ax ; overflow carries into the segment
- and ax,1000h
- add bx,ax
-
- mov ax,di ; calculate a new segment:offset
- mov cl,4
- shr ax,cl
- add bx,ax ; address is bx:0000
-
- mov cx,2048/2
- cld
- rep movsw
-
- mov [bfp+0],cx ; save the new offset
- mov [bfp+2],bx ; save the new segment
-
- call far ptr [bfp] ; go get the table pointer.
-
- mov [tfp+0],ax ; save the function table ptr
- mov [tfp+2],dx
- mov byte ptr ThePASDMAChannel,bl ; save the DMA channel
- mov byte ptr ThePASIRQChannel,cl ; save the IRQ channel
-
- pop si
- pop di
- pop es
-
- }
-
- _asm {
-
- ; for small model, we have to update the segments
-
- mov bx, offset dummyroutine
- mov word ptr [MVSetMixerFunction+0],bx
- mov word ptr [MVSetMixerFunction+2],cs
-
- mov word ptr [MVSetVolumeFunction+0],bx
- mov word ptr [MVSetVolumeFunction+2],cs
-
- mov word ptr [MVSetFilterFunction+0],bx
- mov word ptr [MVSetFilterFunction+2],cs
-
- mov word ptr [MVSetCrossChannel+0],bx
- mov word ptr [MVSetCrossChannel+2],cs
-
- mov word ptr [MVGetMixerFunction+0],bx
- mov word ptr [MVGetMixerFunction+2],cs
-
- mov word ptr [MVGetVolumeFunction+0],bx
- mov word ptr [MVGetVolumeFunction+2],cs
-
- mov word ptr [MVGetFilterFunction+0],bx
- mov word ptr [MVGetFilterFunction+2],cs
-
- mov word ptr [MVGetCrossChannel+0],bx
- mov word ptr [MVGetCrossChannel+2],cs
-
- mov word ptr [MVRealSoundSwitch+0],bx
- mov word ptr [MVRealSoundSwitch+2],cs
-
- mov word ptr [MVFMSplitSwitch+0],bx
- mov word ptr [MVFMSplitSwitch+2],cs
-
- ; deterine if the DOS driver is loaded
-
- mov ax,0xbc00 ; function 0 is for ID
- mov bx,0x3f3f
- sub cx,cx
- sub dx,dx
- int 2fh ; go get it...
- xor bx,cx ; combine all registers
- xor bx,dx
- cmp bx,0x4d56 ; to form 'MV'
- jnz mvininodosdriver
-
- mov ax,0xbc01 ; get the version
- int 2fh
-
- mov word ptr [mvver+0],bx ; save the version
- mov word ptr [mvver+2],cx
-
- ; the DOS driver is loaded, use it's vectors, data, etc
-
- sub cx,cx ; comes back 0 or the entry length
- mov ax,0xbc03 ; get the vector table
- int 0x2f ; from the DOS driver
-
- mov word ptr [tfp+0],bx ; save the function pointer offset
- mov word ptr [tfp+2],dx ; and segment
- mov [tablelen],cx
-
- mov ax,0bc04h ; get the DMA & IRQ
- int 0x2f ; from the DOS driver
-
- mov byte ptr ThePASDMAChannel,bl ; DMA channel
- mov byte ptr ThePASIRQChannel,cl ; IRQ channel
-
- mvininodosdriver:
-
- }
-
- // if the above code did not find the DOS driver, we will attempt to
- // load the DOS mixer driver program located in the caller's path.
-
- if (retcode != DOSDRIVER) { // no dos driver try the disk version
-
- if (path) { // if there is a path, try to load it
-
- // copy the path to working storage
-
- p1 = p = &code_block[2048-64];// build it at the end of buffer
- while ((*p++ = *path++) != 0);
-
- // try to append a '\' to the path
-
- if (*(p-2) != '\\')
- *(p-1) = '\\';
-
- // move the file name
-
- n = 0;
- while ((*p++ = "mixer.drv"[n++]) != 0) ;
-
- // attempt to open the file and read in the driver
-
- _asm {
-
- mov dx,[p1] ; ds:dx points to the file
- mov ax,0x3d00 ; open a file for reading
- int 0x21
-
- jc nofilehere ; skip out if not found
-
- push ds ; save...
-
- lds dx,bfp ; get the storage pointer
- mov bx,ax
- mov cx,2048 ; our max size
- mov ah,0x3f
- int 0x21 ; load the driver
-
- pop ds ; ...restore
-
- pushf
-
- mov ah,0x3e ; close the file
- int 0x21
-
- popf ; get the success flag
- jc nofilehere
-
- call far ptr bfp ; init the code
-
- mov [tfp+0],ax ; save the function table ptr
- mov [tfp+2],dx
-
- mov byte ptr ThePASDMAChannel,bl ; DMA channel
- mov byte ptr ThePASIRQChannel,cl ; IRQ channel
-
- mov retcode,DISKDRIVER ; the disk driver is loaded.
-
- nofilehere:
-
- }
- }
- }
-
- /* check the static driver to see if we can change the state pointer */
-
- _asm {
-
- push es
-
- les bx,bfp
- inc bx
- inc bx
- cmp es:[bx+1],0
- jz nostatefunc ; no, skip the pointer save
- mov [MVMixerHWStateFunction+0],bx ; pointer to state table fetch
- mov [MVMixerHWStateFunction+2],es ; or set function
- ;
- nostatefunc:
- pop es
-
- }
-
- // we have the pointer to some table. Now, load each function pointer into
- // the individual far pointers.
-
- if (mvver > 0x30313032) // ASCII version 0102
- retcode = DOSDRIVER; // indicate the DOS driver is loaded
-
- // set the first 4 (1st rev of MVSOUND just had 4 functions)
-
- (long) MVSetMixerFunction = (long) *tfp++;
- (long) MVSetVolumeFunction = (long) *tfp++;
- (long) MVSetFilterFunction = (long) *tfp++;
- (long) MVSetCrossChannel = (long) *tfp++;
-
- // set the next entries (later revs of MVSOUND had 10 functions)
-
- if (tablelen > 4) {
- (long) MVGetMixerFunction = (long) *tfp++;
- (long) MVGetVolumeFunction = (long) *tfp++;
- (long) MVGetFilterFunction = (long) *tfp++;
- (long) MVGetCrossChannel = (long) *tfp++;
- (long) MVRealSoundSwitch = (long) *tfp++;
- (long) MVFMSplitSwitch = (long) *tfp;
- }
-
- // setup the local drivers state table pointer
-
- if (retcode != DOSDRIVER)
- MVMixerHWState(mvhwShadowPointer);
-
- // return the code
-
- return retcode;
- }
-
-
- ; /*\
- ;---|*|----====< MVMixerHWState >====----
- ;---|*|
- ;---|*| fetch and/or load a pointer to the state table.
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| MVState far * -- pointer to another table. If NULL (0),
- ;---|*| the current pointer is only returned. Only
- ;---|*| non-zero table pointers will be loaded.
- ;---|*| Return Value:
- ;---|*| Returns the pointer to the table currently
- ;---|*| used by the mixer code.
- ;---|*|
- ; \*/
- struct MVState far *MVMixerHWState(tbl)
- struct MVState far *tbl;
- {
-
- if (MVMixerHWStateFunction) { // if there is a function, call it
- _asm {
- mov ax,[tbl+0]
- mov dx,[tbl+2]
- call far ptr [MVMixerHWStateFunction]
- mov [tbl+0],ax
- mov [tbl+2],dx
-
- }
- }
- return (tbl);
- }
-
-
- ; /*\
- ;---|*|----====< static dummyroutine >====----
- ;---|*|
- ;---|*| This routine no-ops out the function calls in case MVSOUND.SYS
- ;---|*| is not loaded.
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| none
- ;---|*|
- ;---|*| Return Value:
- ;---|*| 0
- ;---|*|
- ; \*/
-
- static int dummyroutine ()
- {
- return 0;
- }
-
- /*\
- ;---|*| End of MIXERC.C
- \*/
-
-